package edu.ufl.cise.sanitas.proxy;

/**
 * Concrete class of reliable connection implement
 */
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.security.auth.login.FailedLoginException;

import edu.ufl.cise.sanitas.database.SanitasDBManager;
import edu.ufl.cise.sanitas.types.comm.CreateNewAccountRequest;
import edu.ufl.cise.sanitas.types.comm.CreateNewAccountResponse;
import edu.ufl.cise.sanitas.types.comm.NewPostResponse;
import edu.ufl.cise.sanitas.types.comm.Response;
import edu.ufl.cise.sanitas.types.comm.SigninRequest;
import edu.ufl.cise.sanitas.types.comm.SigninResponse;
import edu.ufl.cise.sanitas.types.comm.Types;
import edu.ufl.cise.sanitas.types.data.Condition;
import edu.ufl.cise.sanitas.types.data.Feed;
import edu.ufl.cise.sanitas.types.data.Newsfeed;
import edu.ufl.cise.sanitas.types.data.User;
import edu.ufl.cise.sanitas.types.comm.*;
import edu.ufl.cise.sanitas.types.comm.Response.Status;
import static edu.ufl.cise.sanitas.types.comm.Response.Status;

public class ReliableConnectionState implements ConnectionState {

	private RequestProcessor proxyServer;
	private SanitasDBManager sdbm;
	
	private byte[] responseData = new byte[10000];
	

	public ReliableConnectionState(RequestProcessor proxyServer,
			SanitasDBManager sdbm) {
		this.proxyServer = proxyServer;
		this.sdbm = sdbm;
	}
	
	@Override
	public byte[] responseData(Response response) {

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos;
		try {
			oos = new ObjectOutputStream(bos);
			
			oos.writeObject(response);
			oos.flush();
			oos.close();
			bos.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		responseData = bos.toByteArray();
		

		return responseData;
	}

	@Override
	public void pushAnalysis() {
		// TODO Auto-generated method stub

	}

	@Override
	public void pushQuery() {
		// TODO Auto-generated method stub

	}

	public String toString() {
		return "Under Reliable Connection State.";
	}

	@Override
	public void testState(String msg) {
		System.out.println("Show msg: " + msg + " under Reliable Connection");
	}

	@Override
	public byte[] createNewAccount(User newUser) {

		int userId = sdbm.createUser(newUser);

		CreateNewAccountResponse cnar;

		if (userId != 0) {
			cnar = new CreateNewAccountResponse(newUser);
		} else {
			cnar = new CreateNewAccountResponse(Status.FAIL, String
					.valueOf(userId));
		}
		
		return responseData(cnar);
	}

	@Override
	public byte[] userLogin(String userName, String pwd) {

		SigninResponse signIn;

		int userId = sdbm.queryUserId(userName, pwd);

//		System.out.println(userId);

		if (userId == 0) {
			signIn = new SigninResponse(Status.FAIL, "Wrong UserName or PWd");
			return responseData(signIn);
		}

		ArrayList<String> condList = new ArrayList<String>();

		condList = sdbm.queryUserCondition(userId);

		Condition[] cond = new Condition[condList.size()];

		for (int i = 0; i < condList.size(); i++) {
			cond[i] = new Condition(condList.get(i));
		}
		
		User loginedUser = sdbm.queryUserProfle(userId);
		
		
		signIn = new SigninResponse(cond, loginedUser);

		return responseData(signIn);
	}

	@Override
	public byte[] bcastNewFeed(Feed newFeed) {
		
		NewPostResponse newFeedResponse;
		
		// insert into db, and returen post info
		
		int userId;
		try {
			userId = sdbm.queryUserId(newFeed.getUserName());
			
			String theme = newFeed.getTheme();
			String content = newFeed.getContent();
			String timeStamp = newFeed.getTheme();
			
			int themeId = sdbm.queryConditionId(theme);
			
			
			// insert into DB
			sdbm.createNewFeed(timeStamp, userId, themeId, content);
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		newFeedResponse = new NewPostResponse(Status.SUCCESS, null);
		
		return responseData(newFeedResponse);
	}

	@Override
	public byte[] fetchAllNewsFeed(int userId) {

		FetchAllNewsfeedResponse fetchResponse;
		
		Newsfeed fetchedFeeds = sdbm.queryUserAllFeeds(userId);
		
		fetchResponse = new FetchAllNewsfeedResponse(Status.SUCCESS, null, fetchedFeeds);

		return responseData(fetchResponse);
	}

	@Override
	public byte[] syncPost() {
		
		SyncPostsResponse syncPostResponse;
		
		syncPostResponse = new SyncPostsResponse(Status.SUCCESS, null);
		
		return responseData(syncPostResponse);
	}

	@Override
	public byte[] updateUserConditions(String userName, String pwd, String[] conditions) {
		
		UpdateUserConditionsResponse upUserCondResponse;
		
		sdbm.updateUserCondition(userName, pwd, conditions);
		
		upUserCondResponse = new UpdateUserConditionsResponse(Status.SUCCESS, null);
		
		return responseData(upUserCondResponse);
	}

	@Override
	public byte[] queryAllConditions() {
		
		QueryAllConditionsResponse queryAllCondsResponse;
		
		String[] condList = sdbm.queryAllCondition();
		
		queryAllCondsResponse = new QueryAllConditionsResponse(Status.SUCCESS, null, condList);
		
		return responseData(queryAllCondsResponse);
	}
}
